using System;
using Hammock;
using WWB.DisqusSharp.Infrastructure.Disqus;
using WWB.DisqusSharp.Model.DisqusDTO;
using WWB.DisqusSharp.Model.DisqusService;

namespace WWB.DisqusSharp.Infrastructure.HammockWrappers
{
    public class HammockDisqusForumService : HammockServiceBase, IDisqusForumService
    {
        public string UserApiKey { get; private set; }
        public string ForumApiKey { get; private set; }
        public string ForumId { get; private set; }


        private RestClient theClient;
        private readonly JsonDotNetSerializer serializer = new JsonDotNetSerializer();

        protected override RestClient GetRestClient()
        {
            if (theClient == null)
            {
                theClient = new RestClient()
                {
                    Authority = DisqusSharpCurrentVersion.Authority,
                };
                theClient.AddParameter("api_version", DisqusSharpCurrentVersion.ApiVersion);
                theClient.UserAgent = DisqusSharpCurrentVersion.UserAgent;
                theClient.Serializer = serializer;
                theClient.Deserializer = serializer;
            }
            return theClient;
        }

        private RestRequest createPostRequest(string path)
        {
            return new RestRequest()
                       {
                           Path = path
                       }
                       .WithField("forum_api_key", ForumApiKey);
        }

        private RestRequest createGetRequest(string path)
        {
            return new RestRequest()
                       {
                           Path = path
                       }
                       .WithParameter("forum_api_key", ForumApiKey);
        }

        public HammockDisqusForumService(string user_api_key, string forum_api_key, string forum_id)
        {
            if (string.IsNullOrWhiteSpace(user_api_key)) throw new ArgumentNullException("user_api_key");
            if (string.IsNullOrWhiteSpace(forum_api_key)) throw new ArgumentNullException("forum_api_key");
            if (string.IsNullOrWhiteSpace(forum_id)) throw new ArgumentNullException("forum_id");
            UserApiKey = user_api_key;
            ForumApiKey = forum_api_key;
            ForumId = forum_id;
        }


        #region Implementation of IDisqusForumService

        public IDisqusServiceResult<DisqusThreadCreationResult> ThreadByIdentifier(string identifier, string title, string category_id, bool create_on_fail)
        {
            var r = createPostRequest(Endpoints.GetThreadByIdentifier)
                .WithField("identifier", identifier)
                .WithField("title", title)
                .WithField("category_id", category_id)
                .WithFieldIfExists("category_id", category_id)
                .WithField("create_on_fail", create_on_fail.ToString());
            return ExecuteRequest<DisqusThreadCreationResult>(r);
        }

        public IDisqusServiceResult<DisqusThread> ThreadByUrl(string url)
        {
            var r = createGetRequest(Endpoints.GetThreadByUrl)
                .WithParameter("forum_api_key", ForumApiKey)
                .WithParameter("url", url);
            return ExecuteRequest<DisqusCategoryIdThread>(r);      
        }

        public IDisqusServiceResult<DisqusThread> UpdateThread(string threadId, UpdateThreadArgs args)
        {
            var r = createPostRequest(Endpoints.UpdateThread)
                .WithField("thread_id", threadId)
                .WithField("url", args.Url)
                .WithField("title", args.Title)
                .WithField("slug", args.Slug)
                .WithField("forum_api_key", ForumApiKey)
                .WithField("allow_comments", Convert.ToInt32(args.AllowComments).ToString());
            return ExecuteRequest<DisqusCategoryIdThread>(r);
        }

        public IDisqusServiceResult<CreatedPost> CreatePost(CreatePostArgs args)
        {
            var r = createPostRequest(Endpoints.CreatePost)
                .WithField("thread_id", args.ThreadId)
                .WithField("message", args.Message)
                .WithField("author_name", args.AuthorName)
                .WithField("author_email", args.AuthorEmail)
                .WithField("createdAt", args.CreatedAt.ToDisqusPostTimeFormat())
                .WithFieldIfExists("ip_address", args.IpAddress)
                .WithFieldIfExists("parent_post", args.ParentPost)
                .WithField("state", "approved");
            return ExecuteRequest<CreatedPost>(r);
        }

        public IDisqusServiceResult<CreatedPost> ModeratePost(string post_id, string action)
        {
            var r = createPostRequest(Endpoints.ModeratePost)
                .WithField("post_id", post_id)
                .WithField("action", action);
            return ExecuteRequest<CreatedPost>(r);
        }


        #endregion
    }
}